home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 52
/
Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso
/
Aminet
/
misc
/
emu
/
Apex-src.lha
/
XREF.XPL
< prev
next >
Wrap
Text File
|
2001-09-30
|
7KB
|
259 lines
\XREF.XPL APR-25-87
\Cross-reference generator for XPL programs.
\ by Loren Blaney
\This program demonstrates the use of binary search trees and linked lists.
\ Ref: Wirth, N., "Algorithms + Data Structures = Programs," (New Jersey:
\ Prentice-Hall, 1976), pp. 206-210.
\
\REVISION HISTORY:
\V1.4, Included underline (_) as an identifier character, L.B.
\V1.5, General clean up, L.B.
\V1.8, Fix "MEMORY FULL" bug caused by ED.XPL program (degenerate trees
\ recurse a lot), L.B.
\MAR-03-85, Modified for 32-bit XPL on the Stride, L.B.
\OCT-20-86, Changed 'ELSE' to 'OTHER' in 'CASE' statements
\APR-11-87, Changed string termination, 8 significant characters in a name.
\APR-25-87, Fixed ^" inside strings.
code RESERVE=3, CHIN=7, CHOUT=8, CRLF=9,
INTIN=10, INTOUT=11, TEXT=12, OPENI=13,
OPENO=14, CLOSE=15, FREE=18;
def TV= 0, KB= 0, FILE= 3; \I/O device numbers
def CR= $0D, LF= $0A, FF= $0C, TAB= $09, EOF= $1A, SP= $20;
def INTSIZE= 4, \Number of bytes in an integer
SIGCHAR= 8, \Number of chars in an identifier
WIDTH= 95, \Width of output device (characters)
NULL= 0; \Empty entry
def \TREEENTRY\ \Components of a tree entry
FIRST, \Pointer to first entry in linked list
LAST, \Pointer to last entry in linked list
LEFT, \Pointer to left branch of tree
RIGHT, \Pointer to right branch of tree
KEY; \Identifier characters (must be last)
def \LISTENTRY\ \Components of a linked-list entry
LNO, \Line number of identifier
NEXT; \Pointer to next entry in the list
addr IDENT; \Identifier character array
int ROOT; \Start of the search tree
int LEN, \Index into IDENT array
LINENO, \Current line no. of the listing
ODEV; \Output device number
reg int CHAR; \The current character read by GETCH
addr TOPMEM, \Top of usable memory (heap) space +1
RAM; \Pointer to allocated heap space
proc GETCH; \Get next character and print it
begin
CHAR:= CHIN(FILE);
if CHAR # EOF then CHOUT(ODEV,CHAR);
end; \GETCH
func ALLOCATE(AMOUNT);
\"Reserves" memory, but, unlike the RESERVE intrinsic, this procedure
\ doesn't return the space to the heap memory pool when the calling
\ procedure returns. In this respect allocate behaves like the Pascal
\ intrinsic "NEW."
int AMOUNT;
addr TEMP;
begin
TEMP:= RAM;
RAM:= RAM + AMOUNT; \Reserve bytes
if RAM >= TOPMEM then
begin
CRLF(TV); TEXT(TV, "OUT OF MEMORY - FILE IS TOO BIG");
CRLF(TV); exit;
end;
return TEMP;
end; \ALLOCATE
proc SEARCH(ADDRTREEENTRY);
\Search the tree. If the identifier is not present then insert it.
\ Otherwise, append the line number to the identifier's linked list.
int ADDRTREEENTRY; \Address of pointer to the tree entry
int TREEENTRY, \Pointer to the tree entry
LISTENTRY, \Pointer to the linked-list entry
N; \Scratch
addr ID; \Identifier character string entry in tree
begin
TREEENTRY:= ADDRTREEENTRY(0);
if TREEENTRY = NULL then \Key is not in tree so insert it
begin
TREEENTRY:= ALLOCATE(SIGCHAR + 4 *INTSIZE);
LISTENTRY:= ALLOCATE(2 *INTSIZE);
ID:= TREEENTRY + KEY *INTSIZE; \Point ID to identifier
for N:= 0, SIGCHAR-1 do ID(N):= IDENT(N);
TREEENTRY(LEFT):= NULL; TREEENTRY(RIGHT):= NULL;
TREEENTRY(FIRST):= LISTENTRY; TREEENTRY(LAST):= LISTENTRY;
LISTENTRY(LNO):= LINENO; LISTENTRY(NEXT):= NULL;
ADDRTREEENTRY(0):= TREEENTRY; \Link up new entry
return;
end;
ID:= TREEENTRY + KEY *INTSIZE; \Point ID to identifier
loop begin
for N:= 0, SIGCHAR-1 do if IDENT(N)#ID(N) then quit;
LISTENTRY:= ALLOCATE(2 *INTSIZE); \Identifier found
LISTENTRY(LNO):= LINENO; \Insert reference no.
LISTENTRY(NEXT):= NULL;
TREEENTRY(LAST,NEXT):= LISTENTRY; \Link new entry in list
TREEENTRY(LAST):= LISTENTRY; \Keep track of last entry
return;
end;
if IDENT(N) < ID(N) then SEARCH(TREEENTRY + LEFT *INTSIZE)
\Pass the address of the pointer for the left branch
else \IDENT(N) > ID(N)\ SEARCH(TREEENTRY + RIGHT *INTSIZE);
end; \SEARCH
proc PRINTENTRY(TREEENTRY);
\Print the identifier name followed by all of its line number references.
\ I.e: print out one tree entry.
int TREEENTRY;
int COLUMN, LISTENTRY, I;
proc STROUT(STR, SIZE); \Output string to ODEV
addr STR;
int SIZE;
int I;
begin
for I:=0, SIZE-1 do
CHOUT(ODEV, STR(I));
end; \STROUT
proc JUSTOUT(N); \Output a right-justified integer
int N; \The field is 6 spaces wide
begin
CHOUT(ODEV, SP);
if N < 10000 then CHOUT(ODEV, SP);
if N < 1000 then CHOUT(ODEV, SP);
if N < 100 then CHOUT(ODEV, SP);
if N < 10 then CHOUT(ODEV, SP);
INTOUT(ODEV,N);
end; \JUSTOUT
begin
STROUT(TREEENTRY + KEY *INTSIZE, SIGCHAR); \Print identifier name
CHOUT(ODEV, SP); CHOUT(ODEV, SP); \Followed by two spaces
COLUMN:= SIGCHAR +2;
\Print the line no. references by following the list linkages
LISTENTRY:= TREEENTRY(FIRST);
repeat begin
if COLUMN+6 >= WIDTH then \New line
[CRLF(ODEV);
for I:= 1, SIGCHAR+2 do CHOUT(ODEV, SP);
COLUMN:= SIGCHAR +2];
JUSTOUT(LISTENTRY(LNO));
COLUMN:= COLUMN +6;
LISTENTRY:= LISTENTRY(NEXT);
end;
until LISTENTRY = NULL;
CRLF(ODEV);
end; \PRINTENTRY
proc PRINTTREE(TREEENTRY);
\Prints the entire tree in (alphabetical) order. I.e. print the cross-
\ reference listing.
int TREEENTRY;
begin
if TREEENTRY # NULL then
begin
PRINTTREE(TREEENTRY(LEFT));
PRINTENTRY(TREEENTRY);
PRINTTREE(TREEENTRY(RIGHT));
end;
end; \PRINTTREE
proc NEWLINE; \Start a new line of the listing
begin
LINENO:= LINENO +1;
INTOUT(ODEV, LINENO); CHOUT(ODEV, TAB);
end; \NEWLINE
begin \MAIN
IDENT:= RESERVE(SIGCHAR);
RAM:= RESERVE(FREE-2000); \Reserve memory for tree & lists
TOPMEM:= RESERVE(0); \Pointer to top of usable memory
TEXT(TV,"-- CROSS REFERENCE, V1.8x3 --
OUTPUT DEVICE? ");
ODEV:= INTIN(KB);
OPENO(ODEV); OPENI(FILE); \Initialize devices
ROOT:= NULL; LINENO:= 0;
NEWLINE;
GETCH;
loop begin
if CHAR = EOF then quit;
if CHAR>=^A & CHAR<=^Z then
begin \Identifier found
LEN:= 0;
repeat if LEN < SIGCHAR then
[IDENT(LEN):= CHAR;
LEN:= LEN +1];
GETCH;
until (CHAR<^A ! CHAR>^Z) & (CHAR<^0 ! CHAR>^9) & CHAR#^_;
\Fill out IDENT with spaces:
for LEN:= LEN, SIGCHAR-1 do IDENT(LEN):= ^ ;
SEARCH(addr ROOT);
end
else begin \Skip strings, comments,
case CHAR of \ reserved words, etc.
^": [repeat GETCH;
if CHAR = ^^ then
[GETCH;
if CHAR = ^" then CHAR:= 0];
if CHAR = EOF then quit;
if CHAR = CR then NEWLINE;
until CHAR = ^";
GETCH];
^\: [repeat GETCH;
if CHAR = EOF then quit;
until CHAR=^\ ! CHAR=CR;
if CHAR = ^\ then GETCH];
^': [repeat GETCH;
if CHAR = EOF then quit;
if CHAR = CR then NEWLINE;
until CHAR = ^';
GETCH];
^^: [GETCH;
if CHAR = EOF then quit;
if CHAR = CR then NEWLINE;
GETCH];
^$: repeat GETCH;
until (CHAR<^0 ! CHAR>^9) & (CHAR<^A ! CHAR>^F)
other GETCH;
end;
if CHAR = CR then NEWLINE;
end;
CRLF(ODEV);
CHOUT(ODEV, FF);
PRINTTREE(ROOT);
CLOSE(ODEV);
end; \MAIN
GETCH;
end;
if CHAR = CR then NEWLINE;
end;
CRLF(ODEV)